package com.weng.cloud.commons.base;

import com.google.gson.Gson;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

/**
 * @Author: weng
 * @Date: 2022/2/18
 * @Description: com.weng.cloud.commons
 * <p>
 * 这里作为一个 静态的、最基础的、简单缺省的 工具类，保证灵活性是最重要的
 * 那么灵活配置的实现，可以开放一个重载方法，允许用户将自己配置的gson传入将来
 * 并且不处理异常
 * 尽量不要过多依赖其他类库，特别是一些简单的操作
 */

public class JsonUtil {

    private final static Gson GSON_DEFAULT;

    static {
        GSON_DEFAULT = new Gson();
    }

    private static Gson gson(Gson gson) {
        return ObjectUtils.firstNonNull(gson, GSON_DEFAULT);
    }

    public static String toText(Object arg, Gson gson) {
        if (arg == null) {
            return null;
        }
        return gson(gson).toJson(arg);
    }

    public static String toText(Object arg) {
        return toText(arg, null);
    }

    public static <T> T toObject(String json, Class<T> clz, Gson gson) {
        if (StringUtils.isBlank(json)) {
            return null;
        } else if (clz == null) {
            return null;
        }
        return gson(gson).fromJson(json, clz);
    }

    public static <T> T toObject(String json, Class<T> clz) {
        return toObject(json, clz, null);
    }

    /**
     * <br/>function:
     * <br/>tip: 默认转成 List<LinkedTreeMap>
     *
     * @param: [json, clz, gson]
     * @return: java.util.List<T>
     * @author: weng
     * @date: 2022/6/12 9:15
     */
    public static <T> List<T> toList(String json, Class<T> clz, Gson gson) {
        if (StringUtils.isBlank(json)) {
            return null;
        } else if (clz == null) {
            return null;
        }

        return gson(gson).fromJson(json, new ParameterizedType() {

            @Override
            public Type[] getActualTypeArguments() {
                return new Type[]{clz};
            }

            @Override
            public Type getRawType() {
                return List.class;
            }

            @Override
            public Type getOwnerType() {
                return null;
            }
        });
    }

    public static <T> List<T> toList(String json, Class<T> clz) {
        return toList(json, clz, null);
    }

    public static Map toMap(String json, Gson gson) {
        return toObject(json, Map.class, gson);
    }

    public static Map toMap(String json) {
        return toMap(json, null);
    }
}
